package com.hpsk.shopservice.model.config.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hpsk.common.CommonException;
import com.hpsk.shopservice.model.config.dto.BizConfigMenuAddDto;
import com.hpsk.shopservice.model.config.dto.BizConfigMenuDto;
import com.hpsk.shopservice.model.config.entity.BizConfigMenu;
import com.hpsk.shopservice.model.config.dao.BizConfigMenuMapper;
import com.hpsk.shopservice.model.config.service.IBizConfigMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hpsk.shopservice.model.config.vo.BizConfigMenuVo;
import com.hpsk.shopservice.model.config.vo.MenuVo;
import io.github.linpeilie.Converter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 列表控制器 服务实现类
 * </p>
 *
 * @author huangwang
 * @since 2025-03-20
 */
@Service
@Slf4j
@AllArgsConstructor(onConstructor_ = @__(@Autowired))
public class BizConfigMenuServiceImpl extends ServiceImpl<BizConfigMenuMapper, BizConfigMenu> implements IBizConfigMenuService {

    private final Converter converter;

    @Override
    public BizConfigMenuVo add(BizConfigMenuAddDto bizConfigMenuAddDto) {
        BizConfigMenu convert = converter.convert(bizConfigMenuAddDto, BizConfigMenu.class);
        if (ObjectUtil.isEmpty(convert.getParentId())) {
            BizConfigMenu detail = getOne(getQueryWrapper(BizConfigMenuDto.builder().name(convert.getName()).level(1).build()));
            if (detail != null) {
                throw new CommonException("菜单名称重复，无法创建！");
            }
            convert.setLevel(1);
        } else {
            BizConfigMenu detail = getOne(getQueryWrapper(BizConfigMenuDto.builder().name(convert.getName()).parentId(convert.getParentId()).build()));
            if (detail != null) {
                throw new CommonException("菜单名称重复，无法创建！");
            }
            BizConfigMenuVo parentDetail = detail(convert.getParentId());
            convert.setLevel(parentDetail.getLevel() + 1);
            convert.setParentId(parentDetail.getId());
        }
        save(convert);
        return converter.convert(convert, BizConfigMenuVo.class);
    }

    @Override
    public BizConfigMenuVo detail(Long id) {

        BizConfigMenu one = getOne(getQueryWrapper(BizConfigMenuDto.builder().id(id).build()));
        if (one == null) {
            throw new CommonException("菜单不存在！");
        }
        return converter.convert(one, BizConfigMenuVo.class);
    }

    @Override
    public BizConfigMenuVo detail(BizConfigMenuDto configMenuDto) {

        BizConfigMenu one = getOne(getQueryWrapper(configMenuDto));
        if (one == null) {
            throw new CommonException("菜单不存在！");
        }
        return converter.convert(one, BizConfigMenuVo.class);
    }

    @Override
    public List<MenuVo> getAllList() {
        List<MenuVo> list = new ArrayList<>();
        List<BizConfigMenu> configMenus = list();
        Map<Integer, List<BizConfigMenu>> levelMap =
                configMenus.stream().collect(Collectors.groupingBy(BizConfigMenu::getLevel));
        List<BizConfigMenu> level1 = levelMap.get(1);
        List<BizConfigMenu> level2 = levelMap.get(2);
        List<BizConfigMenu> level3 = levelMap.get(3);
        Map<Long, List<BizConfigMenu>> level2Map = new HashMap<>();
        Map<Long, List<BizConfigMenu>> level3Map = new HashMap<>();
        if (ObjectUtil.isNotEmpty(level2)) {
            level2Map = level2.stream().sorted(Comparator.comparing(BizConfigMenu::getSort).thenComparing(BizConfigMenu::getId)).collect(Collectors.groupingBy(BizConfigMenu::getParentId));
            if (ObjectUtil.isNotEmpty(level3)) {
                level3Map = level3.stream().sorted(Comparator.comparing(BizConfigMenu::getSort).thenComparing(BizConfigMenu::getId)).collect(Collectors.groupingBy(BizConfigMenu::getParentId));
            }
        }
        if (ObjectUtil.isNotEmpty(level1)) {
            level1.sort(Comparator.comparing(BizConfigMenu::getSort).thenComparing(BizConfigMenu::getId));
            for (BizConfigMenu item : level1) {
                MenuVo menuVo = getMenuVo(item);
                //二级
                List<BizConfigMenu> configMenus2 = level2Map.get(item.getId());
                if (ObjectUtil.isNotEmpty(configMenus2)) {
                    for (BizConfigMenu item2 : configMenus2) {
                        if (item2.getParentId().equals(item.getId())) {
                            MenuVo menuVo2 = getMenuVo(item2);
                            //三级
                            List<BizConfigMenu> configMenus3 = level3Map.get(item2.getId());
                            if (ObjectUtil.isNotEmpty(configMenus3)) {
                                configMenus3.stream().map(BizConfigMenuServiceImpl::getMenuVo).forEach(menuVo3 -> menuVo2.getChildList().add(menuVo3));
                            }
                            menuVo.getChildList().add(menuVo2);
                        }
                    }
                }
                list.add(menuVo);
            }
        }
        return list;
    }

    @Override
    public BizConfigMenuVo updateMenu(BizConfigMenuAddDto bizConfigMenuAddDto) {
        Long id = bizConfigMenuAddDto.getId();
        BizConfigMenuVo configMenuVo = detail(id);
        BizConfigMenu convert = converter.convert(bizConfigMenuAddDto, BizConfigMenu.class);
        convert.setParentId(null);
        updateById(convert);
        return null;
    }

    private static MenuVo getMenuVo(BizConfigMenu item) {
        return MenuVo.builder()
                .id(item.getId())
                .name(item.getName())
                .level(item.getLevel())
                .parentId(item.getParentId())
                .sort(item.getSort())
                .routerUrl(item.getRouterUrl())
                .icon(item.getIcon())
//                .label(item.getName())
                .createUser(item.getCreateUser())
                .createTime(item.getCreateTime())
                .updateUser(item.getUpdateUser())
                .updateTime(item.getUpdateTime())
                .build();
    }

    private static LambdaQueryWrapper<BizConfigMenu> getQueryWrapper(BizConfigMenuDto configMenuDto) {

        LambdaQueryWrapper<BizConfigMenu> wrapper = Wrappers.<BizConfigMenu>lambdaQuery();
        if (ObjectUtil.isNotEmpty(configMenuDto)) {
            wrapper.eq(ObjectUtil.isNotEmpty(configMenuDto.getId()), BizConfigMenu::getId, configMenuDto.getId());
            wrapper.eq(ObjectUtil.isNotEmpty(configMenuDto.getLevel()), BizConfigMenu::getLevel, configMenuDto.getLevel());
            wrapper.eq(ObjectUtil.isNotEmpty(configMenuDto.getParentId()), BizConfigMenu::getParentId, configMenuDto.getParentId());
            wrapper.eq(ObjectUtil.isNotEmpty(configMenuDto.getName()), BizConfigMenu::getName, configMenuDto.getName());
        }
        return wrapper;
    }
}
